package al.xc.common.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * 时间工具类
 */
public class TimeUtils {

    private final static SelfThreadLocal<SimpleDateFormat> shortSDF = new SelfThreadLocal(() -> new SimpleDateFormat("yyyy-MM-dd"));
    private final static SelfThreadLocal<SimpleDateFormat> longSDF = new SelfThreadLocal(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    private final static SelfThreadLocal<SimpleDateFormat> longHourSDF = new SelfThreadLocal(() -> new SimpleDateFormat("yyyy-MM-dd HH"));
    private final static SelfThreadLocal<SimpleDateFormat> timeSDF = new SelfThreadLocal(() -> new SimpleDateFormat("HH:mm:ss"));

    /**
     * 获取系统距离1970年1月1日总毫秒
     * @return 距离1970年1月1日总毫秒
     */
    public static long getTotalMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 增加秒数
     * @param date
     * @param seconds
     * @return
     */
    public static Date addTime(Date date, Integer seconds) {
        return addTime(date, Calendar.SECOND, seconds);
    }

    /**
     * 增加时间
     * @param date
     * @param type
     * @param value
     * @return
     */
    public static Date addTime(Date date, Integer type, Integer value) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(type, value);
        return cal.getTime();
    }

    /**
     * 间隔时间(毫秒)
     * @param left
     * @param right
     * @return
     */
    public static Long diffTime(Date left, Date right) {
        return left.getTime() - right.getTime();
    }

    /**
     * 获得今天对应的时间
     * @param date
     * @return
     */
    public static Date withNowDate(Date date) {
        String shortDate = shortSDF.get().format(new Date());
        String shortTime = timeSDF.get().format(date);
        try {
            return longSDF.get().parse(shortDate + " " + shortTime);
        } catch (Exception ex) {}
        return null;
    }

    /**
     * 日期去掉时间
     * @param date
     * @return
     */
    public static Date withoutTime(Date date) {
        String s = shortSDF.get().format(date);
        try {
            date = shortSDF.get().parse(s);
        } catch (Exception ex){}

        return date;
    }

    /**
     * 小时开始时间
     * @param date
     * @return
     */
    public static Date hourBegin(Date date) {
        try {
            return longHourSDF.get().parse(longHourSDF.get().format(date));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return date;
    }

    /**
     * 小时结束时间
     * @param date
     * @return
     */
    public static Date hourEnd(Date date) {
        try {
            return longSDF.get().parse(longHourSDF.get().format(date) + ":59:59");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return date;
    }

    /**
     * 天开始时间
     * @param date
     * @return
     */
    public static Date dayBegin(Date date) {
        return withoutTime(date);
    }

    /**
     * 天结束时间
     * @param date
     * @return
     */
    public static Date dayEnd(Date date) {
        try {
            return longSDF.get().parse(shortSDF.get().format(date) + " 23:59:59");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return date;
    }

    /**
     * 一周的开始
     * @return
     */
    public static Date weekBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        try {
            int weekDay = cal.get(Calendar.DAY_OF_WEEK) - 2;
            cal.add(Calendar.DATE, -weekDay);
            cal.setTime(shortSDF.get().parse(shortSDF.get().format(cal.getTime())));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return cal.getTime();
    }

    /**
     * 一周的结束
     * @param date
     * @return
     */
    public static Date weekEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int weekDay = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DATE, 8 - weekDay);
        try {
            return longSDF.get().parse(shortSDF.get().format(cal.getTime()) + " 23:59:59");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /*
     * 月开始时间
     */
    public static Date monthBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        try {
            cal.set(Calendar.DATE, 1);
            return shortSDF.get().parse(shortSDF.get().format(cal.getTime()));
        }catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /*
     * 月结束时间
     */
    public static Date monthEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        try {
            cal.set(Calendar.DATE, 1);
            cal.add(Calendar.MONTH, 1);
            cal.add(Calendar.DATE, -1);
            return longSDF.get().parse(shortSDF.get().format(cal.getTime()) + " 23:59:59");
        }catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 季度开始时间
     * @param date
     * @return
     */
    public static Date QuarterBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int currentMonth = cal.get(Calendar.MONTH) + 1;
        try {
            if (currentMonth > 0 && currentMonth <= 3) {
                cal.set(Calendar.MONTH, 0);
            } else if (currentMonth > 3 && currentMonth <= 6) {
                cal.set(Calendar.MONTH, 3);
            } else if (currentMonth > 6 && currentMonth <= 9) {
                cal.set(Calendar.MONTH, 6);
            } else {
                cal.set(Calendar.MONTH, 9);
            }
            cal.set(Calendar.DATE, 1);
            return shortSDF.get().parse(shortSDF.get().format(cal.getTime()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 季度结束时间
     * @param date
     * @return
     */
    public static Date QuarterEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int currentMonth = cal.get(Calendar.MONTH) + 1;
        try {
            if (currentMonth > 0 && currentMonth <= 3) {
                cal.set(Calendar.MONTH, 2);
                cal.set(Calendar.DATE, 31);
            } else if (currentMonth > 3 && currentMonth <= 6) {
                cal.set(Calendar.MONTH, 5);
                cal.set(Calendar.DATE, 30);
            } else if (currentMonth > 6 && currentMonth <= 9) {
                cal.set(Calendar.MONTH, 8);
                cal.set(Calendar.DATE, 30);
            } else {
                cal.set(Calendar.MONTH, 11);
                cal.set(Calendar.DATE, 31);
            }
            return longSDF.get().parse(shortSDF.get().format(cal.getTime()) + " 23:59:59");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 前/后半年开始时间
     * @param date
     * @return
     */
    public static Date halfYearBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int currentMonth = cal.get(Calendar.MONTH) + 1;
        try {
            if (currentMonth > 0 && currentMonth <=6 ) {
                cal.set(Calendar.MONTH, 0);
            } else {
                cal.set(Calendar.MONTH, 6);
            }
            cal.set(Calendar.DATE, 1);
            return shortSDF.get().parse(shortSDF.get().format(cal.getTime()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 前/后半年结束时间
     * @param date
     * @return
     */
    public static Date halfYearEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int currentMonth = cal.get(Calendar.MONTH) + 1;
        try {
            if (currentMonth > 0 && currentMonth <=6 ) {
                cal.set(Calendar.MONTH, 5);
                cal.set(Calendar.DATE, 30);
            } else {
                cal.set(Calendar.MONTH, 11);
                cal.set(Calendar.DATE, 31);
            }
            return longSDF.get().parse(shortSDF.get().format(cal.getTime()) + " 23:59:59");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 年开始时间
     * @param date
     * @return
     */
    public static Date yearBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        try {
            cal.set(Calendar.MONTH, 0);
            cal.set(Calendar.DATE, 1);
            return shortSDF.get().parse(shortSDF.get().format(cal.getTime()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 年结束时间
     * @param date
     * @return
     */
    public static Date yearEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        try {
            cal.set(Calendar.MONTH, 11);
            cal.set(Calendar.DATE, 31);
            return longSDF.get().parse(shortSDF.get().format(cal.getTime()) + " 23:59:59");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 获取系统时间
     * @return 系统时间
     */
    private static Calendar getCalendar() {
        Calendar nowCalendar = Calendar.getInstance();
        nowCalendar.setTime(new Date());
        return nowCalendar;
    }

    /**
     * 格式化输出时间
     * @param time
     * @param format
     * @return
     */
    public static String formatTime(Date time, String format, TimeZone tz) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        if (null != tz) {
            sdf.setTimeZone(tz);
        }
        return sdf.format(time);
    }
}
